# include "PNJ.h"

# include "Renderer.h"

PNJ::PNJ() : Personage()
{

}

PNJ::~PNJ()
{

}

void PNJ::setCurrentDialog( const std::string& currentDialog)
{
	myCurrentDialog = currentDialog;
}

const std::string& PNJ::getCurrentDialog()
{
	return myCurrentDialog;
}

void PNJ::addQuestActivated( const std::string& nameQuest)
{
	myQuestsActivated.push_back( nameQuest);
}

void PNJ::init( Renderer* renderer, const std::string& lua, const std::string& luaTalk)
{
	myRenderer = renderer;
	myLua = lua;
	myLuaTalk = luaTalk;
}

void PNJ::load( const std::string& name)
{
	lua_State* stateTmp = lua_open();
	luaL_openlibs( stateTmp);
	luaL_dofile( stateTmp, myLua.c_str());
	lua_settop( stateTmp, 0);

	lua_getglobal( stateTmp, name.c_str());

	lua_pushnumber( stateTmp, 1);
	lua_gettable( stateTmp, -2);
	myName = lua_tostring( stateTmp, -1);
	lua_pop( stateTmp, 1);

	mySceneNode = myRenderer->createSceneNode( "PNJNode");

	lua_pushnumber( stateTmp, 2);
	lua_gettable( stateTmp, -2);
	myBody = myRenderer->createEntity( "PNJ", lua_tostring( stateTmp, -1));
	lua_pop( stateTmp, 1);

	myBodyNode = mySceneNode->createChildSceneNode( "PNJBodyNode");
	myBodyNode->showBoundingBox( true);
	
	myBody->setQueryFlags( PNJ_FLAG);
	myBodyNode->attachObject( myBody);
	setSize( 20.0f);

	loadTalk( name);

	lua_pop( stateTmp, 1);
	lua_close( stateTmp);
}

void PNJ::loadTalk( const std::string& name)
{
	lua_State* stateTmp = lua_open();
	luaL_openlibs( stateTmp);
	luaL_dofile( stateTmp, myLuaTalk.c_str());
	lua_settop( stateTmp, 0);	
	int indiceTmp = 1;

	lua_getglobal( stateTmp, name.c_str());

	lua_pushnumber( stateTmp, indiceTmp++);
	lua_gettable( stateTmp, -2);
	unsigned int numberTmp = lua_tonumber( stateTmp, -1);
	lua_pop( stateTmp, 1);

	for ( unsigned int i = 0; i < numberTmp; i++ )
	{
		lua_pushnumber( stateTmp, indiceTmp++);
		lua_gettable( stateTmp, -2);
		std::string talkTmp = lua_tostring( stateTmp, -1);
		lua_pop( stateTmp, 1);
		
		myDialog.insert( std::pair<std::string, PieceDialog*>( talkTmp, new PieceDialog()));

		lua_pushnumber( stateTmp, indiceTmp++);
		lua_gettable( stateTmp, -2);
		myDialog[talkTmp]->action = lua_tonumber( stateTmp, -1);
		lua_pop( stateTmp, 1);

		if ( myDialog[talkTmp]->action == 1 )
		{
			lua_pushnumber( stateTmp, indiceTmp++);
			lua_gettable( stateTmp, -2);
			myDialog[talkTmp]->questName = new std::string( lua_tostring( stateTmp, -1));
			lua_pop( stateTmp, 1);
		}

		if ( myDialog[talkTmp]->action != 3 )
		{
			lua_pushnumber( stateTmp, indiceTmp++);
			lua_gettable( stateTmp, -2);
			myDialog[talkTmp]->pnjTalk = lua_tostring( stateTmp, -1);
			lua_pop( stateTmp, 1);

			lua_pushnumber( stateTmp, indiceTmp++);
			lua_gettable( stateTmp, -2);
			unsigned int number2Tmp = lua_tonumber( stateTmp, -1);
			lua_pop( stateTmp, 1);

			for ( unsigned int j = 0; j < number2Tmp; j++ )
			{
				lua_pushnumber( stateTmp, indiceTmp++);
				lua_gettable( stateTmp, -2);
				myDialog[talkTmp]->answers.push_back( new std::string( lua_tostring( stateTmp, -1)));
				lua_pop( stateTmp, 1);
			
				lua_pushnumber( stateTmp, indiceTmp++);
				lua_gettable( stateTmp, -2);
				myDialog[talkTmp]->destinations.push_back( new std::string( lua_tostring( stateTmp, -1)));
				lua_pop( stateTmp, 1);
			}
		}

		else
		{
			lua_pushnumber( stateTmp, indiceTmp++);
			lua_gettable( stateTmp, -2);
			myDialog[talkTmp]->destinations.push_back( new std::string( lua_tostring( stateTmp, -1)));
		}
	}

	myCurrentDialog = "Welcome";

	lua_pop( stateTmp, 1);
	lua_close( stateTmp);
}

void PNJ::loadQuest( const std::string& name, unsigned int currentState)
{
	std::ostringstream streamTmp;
	streamTmp << currentState;
	std::string nameQuest = myName + name + streamTmp.str();

	lua_State* stateTmp = lua_open();
	luaL_openlibs( stateTmp);
	luaL_dofile( stateTmp, myLuaTalk.c_str());
	lua_settop( stateTmp, 0);
	int indiceTmp = 1;

	lua_getglobal( stateTmp, nameQuest.c_str());

	lua_pushnumber( stateTmp, indiceTmp++);
	lua_gettable( stateTmp, -2);
	myDialog[myCurrentDialog]->answers.push_front( new std::string( lua_tostring( stateTmp, -1)));

	if ( myCurrentDialog == "Welcome" )
	{
		myDialog["Second Welcome"]->answers.push_front( new std::string( lua_tostring( stateTmp, -1)));
	}

	lua_pop( stateTmp, 1);

	lua_pushnumber( stateTmp, indiceTmp++);
	lua_gettable( stateTmp, -2);
	myDialog[myCurrentDialog]->destinations.push_front( new std::string( lua_tostring( stateTmp, -1)));

	if ( myCurrentDialog == "Welcome" )
	{
		myDialog["Second Welcome"]->destinations.push_front( new std::string( lua_tostring( stateTmp, -1)));
	}

	lua_pop( stateTmp, 1);

	lua_pushnumber( stateTmp, indiceTmp++);
	lua_gettable( stateTmp, -2);
	unsigned int numberTmp = lua_tonumber( stateTmp, -1);
	lua_pop( stateTmp, 1);
	
	for ( unsigned int i = 0; i < numberTmp; i++ )
	{
		lua_pushnumber( stateTmp, indiceTmp++);
		lua_gettable( stateTmp, -2);
		std::string talkTmp = lua_tostring( stateTmp, -1);
		lua_pop( stateTmp, 1);
		
		myDialog.insert( std::pair<std::string, PieceDialog*>( talkTmp, new PieceDialog()));

		lua_pushnumber( stateTmp, indiceTmp++);
		lua_gettable( stateTmp, -2);
		myDialog[talkTmp]->action = lua_tonumber( stateTmp, -1);
		lua_pop( stateTmp, 1);

		if ( myDialog[talkTmp]->action == ACTIVE_QUEST )
		{
			lua_pushnumber( stateTmp, indiceTmp++);
			lua_gettable( stateTmp, -2);
			myDialog[talkTmp]->questName = new std::string( lua_tostring( stateTmp, -1));
			lua_pop( stateTmp, 1);
		}

		else if ( myDialog[talkTmp]->action == NEXT_STEP_QUEST )
		{
			lua_pushnumber( stateTmp, indiceTmp++);
			lua_gettable( stateTmp, -2);
			myDialog[talkTmp]->questName = new std::string( lua_tostring( stateTmp, -1));
			lua_pop( stateTmp, 1);
		}

		if ( myDialog[talkTmp]->action != 3 )
		{
			lua_pushnumber( stateTmp, indiceTmp++);
			lua_gettable( stateTmp, -2);
			myDialog[talkTmp]->pnjTalk = lua_tostring( stateTmp, -1);
			lua_pop( stateTmp, 1);

			lua_pushnumber( stateTmp, indiceTmp++);
			lua_gettable( stateTmp, -2);
			unsigned int number2Tmp = lua_tonumber( stateTmp, -1);
			lua_pop( stateTmp, 1);

			for ( unsigned int j = 0; j < number2Tmp; j++ )
			{
				lua_pushnumber( stateTmp, indiceTmp++);
				lua_gettable( stateTmp, -2);
				myDialog[talkTmp]->answers.push_back( new std::string( lua_tostring( stateTmp, -1)));
				lua_pop( stateTmp, 1);
			
				lua_pushnumber( stateTmp, indiceTmp++);
				lua_gettable( stateTmp, -2);
				myDialog[talkTmp]->destinations.push_back( new std::string( lua_tostring( stateTmp, -1)));
				lua_pop( stateTmp, 1);
			}
		}

		else
		{
			lua_pushnumber( stateTmp, indiceTmp++);
			lua_gettable( stateTmp, -2);
			myDialog[talkTmp]->destinations.push_back( new std::string( lua_tostring( stateTmp, -1)));
		}
	} 
}

void PNJ::unloadQuest( const std::string& name)
{
	std::string nameQuest = myName + name + "Out";

	lua_State* stateTmp = lua_open();
	luaL_openlibs( stateTmp);
	luaL_dofile( stateTmp, myLuaTalk.c_str());
	lua_settop( stateTmp, 0);
	int indiceTmp = 1;

	lua_getglobal( stateTmp, nameQuest.c_str());

	lua_pushnumber( stateTmp, indiceTmp++);
	lua_gettable( stateTmp, -2);
	unsigned int numberTmp = lua_tonumber( stateTmp, -1);
	lua_pop( stateTmp, 1);

	for ( unsigned int i = 0; i < numberTmp; i++ )
	{
		lua_pushnumber( stateTmp, indiceTmp++);
		lua_gettable( stateTmp, -2);
		std::string testTmp = lua_tostring( stateTmp, -1);
		lua_pop( stateTmp, 1);

		for ( unsigned int i = 0; i < myDialog["Second Welcome"]->answers.size(); i++ )
		{
			if ( testTmp == *(myDialog["Second Welcome"]->answers[i]) )
			{
				delete myDialog["Second Welcome"]->answers[i];
				delete myDialog["Second Welcome"]->destinations[i];

				myDialog["Second Welcome"]->answers.erase( myDialog["Second Welcome"]->answers.begin() + i);
				myDialog["Second Welcome"]->destinations.erase( myDialog["Second Welcome"]->destinations.begin() + i);
			}
		}

		for ( unsigned int i = 0; i < myDialog["Welcome"]->answers.size(); i++ )
		{
			if ( testTmp == *(myDialog["Welcome"]->answers[i]) )
			{
				delete myDialog["Welcome"]->answers[i];
				delete myDialog["Welcome"]->destinations[i];

				myDialog["Welcome"]->answers.erase( myDialog["Welcome"]->answers.begin() + i);
				myDialog["Welcome"]->destinations.erase( myDialog["Welcome"]->destinations.begin() + i);
			}
		}
	}

	lua_pushnumber( stateTmp, indiceTmp++);
	lua_gettable( stateTmp, -2);
	numberTmp = lua_tonumber( stateTmp, -1);
	lua_pop( stateTmp, 1);

	for ( unsigned int i = 0; i < numberTmp; i++ )
	{
		lua_pushnumber( stateTmp, indiceTmp++);
		lua_gettable( stateTmp, -2);
		std::string testTmp = lua_tostring( stateTmp, -1);
		lua_pop( stateTmp, 1);

		if ( myDialog.find( testTmp) != myDialog.end() )
		{
			while ( myDialog[testTmp]->answers.size() )
			{
				delete myDialog[testTmp]->answers.front();
				myDialog[testTmp]->answers.pop_front();
			}

			while ( myDialog[testTmp]->destinations.size() )
			{
				delete myDialog[testTmp]->destinations.front();
				myDialog[testTmp]->destinations.pop_front();
			}

			if ( myDialog[testTmp]->action == ACTIVE_QUEST )
			{
				delete myDialog[testTmp]->questName;
			}

			delete myDialog[testTmp];
			myDialog.erase( myDialog.find( testTmp));
		}
	}

	lua_pop( stateTmp, 1);
	lua_close( stateTmp);
}

void PNJ::oneFrame()
{
	for ( unsigned int i = 0; i < myQuestsActivated.size(); i++ )
	{
		unloadQuest( myQuestsActivated[i]);
	}

	myQuestsActivated.clear();
}

void PNJ::activateQuest( Quest* quest)
{
	if ( quest->name == "First" )
	{
		if ( quest->current == 1 )
		{
		}
	}
}

void PNJ::desactivateQuest( Quest* quest)
{
	if ( quest->name == "First" )
	{
		if ( quest->current == 1 )
		{
			/*delete myDialog[5]->answers.front();
			myDialog[5]->answers.pop_front();
			myDialog[5]->destinations.pop_front();*/
		}
	}
}

PieceDialog* PNJ::findPieceDialog( const std::string& name)
{
	if ( myDialog.find( name) != myDialog.end() )
	{
		return myDialog[name];
	}

	return NULL;
}